<template>
  <a-modal v-model:open="open" :title="title" @ok="ok" :width="700">
    <a-alert class="alert" :class="mode=='javascript'&&alert_type!='error'?'alert-js':''" :message="message_alert" :type="alert_type" v-if="showAlert" />
    <div class="ace-container">
      <div class="ace-editor" ref="ace_ref"></div>
    </div>
    <a-alert class="alert alert-js" :message="' }' " type="success" v-if="showAlert_bottom" />
  </a-modal>
</template>

<script setup>
import { ref, defineProps, defineEmits, defineModel, computed, watch, nextTick } from 'vue'

import ace from "ace-code/esm-resolver";
import "ace-code/src/ext/language_tools";
import { LanguageProvider } from "ace-linters";
import { isJsonString } from '@/utils/util';

let worker = new Worker(new URL('./webworker.js', import.meta.url));
let languageProvider = LanguageProvider.create(worker);

const props = defineProps({
  modelValue: {
    type: String
  },
  mode: {
    type: String,
    default: 'javascript'
  },
  message: String,
  title: String,
})

let editor = null
const open = defineModel('open')
const showAlert = ref(true)
const _message = ref(props.message)
const alert_type = ref('success')
const emits = defineEmits(['update:modelValue'])
const ace_ref = ref(null)

const ok = () => {
  if (editor == null) return;
  if (props.mode == 'json') {
    if (isJsonString(editor.getValue())) {
      emits('update:modelValue', editor.getValue())
    } else {
      showAlert.value = true
      _message.value = 'JSON数据格式错误'
      alert_type.value = 'error'
      return;
    }
  } else if(props.mode == 'javascript') {
    if (editor.getSession().getAnnotations().length == 0) {
      emits('update:modelValue', editor.getValue())
    } else {
      showAlert.value = true
      _message.value = '函数格式错误'
      alert_type.value = 'error'
      return;
    }
  }
  open.value = false
}

const showAlert_bottom = computed(() => {
  return props.mode == 'javascript' && alert_type.value != 'error'
})

const ace_init = () => {
  if (editor == null) {
    editor = ace.edit(ace_ref.value, {
      maxLines: 20, // 最大行数，超过会自动出现滚动条
      minLines: 20, // 最小行数，还未到最大行数时，编辑器会自动伸缩大小
      fontSize: 14, // 编辑器内字体大小
      theme: 'ace/theme/chrome', // 默认设置的主题
      mode: "ace/mode/" + props.mode, // 默认设置的语言模式
      tabSize: 2, // 制表符设置为2个空格大小
      readOnly: false,
      useWorker: true,
      highlightActiveLine: true,
      value: props.modelValue,
      enableBasicAutocompletion: true,
      enableSnippets: true,  // 设置代码片段提示
      enableLiveAutocompletion: true,  // 设置自动提示
    })

    languageProvider.registerEditor(editor);

    // editor.getSession().on('change', () => {
    //   if (editor.getSession().getAnnotations().length == 0) {
    //     _message.value = props.message
    //     alert_type.value = 'success'
    //   }
    // })
  } else {
    editor.setOptions({
      mode: "ace/mode/" + props.mode,
      value: props.modelValue,
    })
  }
}

const message_alert = computed(() => {
  if (props.mode == 'javascript' && alert_type.value == 'success') {
    return _message.value + '() {'
  } else {
    return _message.value
  }
})

watch(open, (status) => { 
  if (status) {
    _message.value = props.message
    alert_type.value = 'success'

    if (props.mode == 'json') {
      showAlert.value = false
    } else {
      showAlert.value = true
    }
    nextTick(() => {
      ace_init()
    })
  } else {
    if (editor) {
      editor.destroy();
      nextTick(() => {
        editor = null
      })
    }
  }
})

</script>

<style lang="less" scoped>
.alert{
  border: 0;
  border-radius: 0;
}
.alert-js{
  color: #909399;
  background-color: #f4f4f5;
}
</style>